package com.xgk.boot.module.core.ui;

import com.xgk.boot.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.xgk.boot.framework.common.pojo.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.WebRequest;

import java.util.HashMap;
import java.util.Map;

/**
 * 全局异常处理
 */
@Slf4j
public class BootErrorAttributes extends DefaultErrorAttributes {

    public static final String STATUS = "status";
    public static final String REDIRECT = "redirect";
    public static final String DEFAULT_INDEX = "index.html";
    /**
     * 如果找不到，就默认到当前路径下的index.html
     */
    private final boolean goToIndex = true;

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions includeStackTrace) {
        String requestUri = this.getAttr(webRequest, "javax.servlet.error.request_uri");
        Integer status = this.getAttr(webRequest, "javax.servlet.error.status_code");
        Throwable error = getError(webRequest);
        CommonResult result;
        if (goToIndex && status == HttpStatus.NOT_FOUND.value()) {
            Map<String, Object> errorAttr = new HashMap<>();
            errorAttr.put(STATUS, HttpStatus.MOVED_PERMANENTLY.value());
            errorAttr.put(REDIRECT, getIndex(requestUri));
            return errorAttr;
        } else {
            if (error == null) {
                log.error("URL:{} error status:{}", requestUri, status);
                result = CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST, "系统未知异常[HttpStatus]:" + status);
            } else {
                log.error(String.format("URL:%s error status:%d", requestUri, status), error);
                result = CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST, error.getMessage());
            }
            //发送服务异常事件
            try {
                Map<String, Object> resultMap = new HashMap<>();
                BeanUtils.copyProperties(result, resultMap);
                return resultMap;
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }

    }

    private String getIndex(String uri) {
//        StringBuilder index = new StringBuilder();
//        int splitCount = 0;
//        for (int i = 0; i < uri.length(); i++) {
//            char c = uri.charAt(i);
//            if (c == '/') {
//                splitCount++;
//            }
//            index.append(c);
//            if (splitCount >= 2) {
//                break;
//            }
//        }
//        index.append(DEFAULT_INDEX);
//        return index.toString();
        return DEFAULT_INDEX;
    }

    @Nullable
    private <T> T getAttr(WebRequest webRequest, String name) {
        return (T) webRequest.getAttribute(name, RequestAttributes.SCOPE_REQUEST);
    }

}
